<?php

/**
 * @author gbfun <gbfun@163.com>  2018-11-15 16:35
 * http://www.wuweiyou.com
 */

class wwy_cache_handler
{ 
    protected $_cache_instance = null;
    
    protected $_if_global_cache = true;    //@by gbfun 全局缓存开关
    //protected $_if_global_cache = false;
    
    protected $_unique_key = 'app_unique_key';    //避免有多个类似应用时，出现【缓存键名】冲突
    
    private function __clone()
    {
    }
    
    
    public function __construct($options)
    {
        if(isset($options['cache_instance'])){
            $this->_set_cache_instance($options['cache_instance']);
        }        
        
        if(isset($options['if_global_cache'])){
            $this->_if_global_cache = $options['if_global_cache'];
        }
        
        if(!empty($options['unique_key'])){
            $this->_unique_key = $options['unique_key'];
        }        
    }
    
    protected function _set_cache_instance($cache_instance_options)
    {
        $cache_instance_type = $cache_instance_options['type'];
        $cache_instance_params = $cache_instance_options['params'];
        
        if($cache_instance_type == 'memcache'){
            $this->_cache_instance = new Memcache;
            $this->_cache_instance->connect($cache_instance_params['host'], $cache_instance_params['port']);    //@by gbfun
        }
        
        //定义【其他缓存实例创】建方法
        if($cache_instance_type == 'redis'){            
            //【其他缓存实例创】必须有【set(), get(), flush()方法。若无，则必须【自定义新类】实现
        }       
    }
    
    protected function _set($key, $var, $flag = null, $expire = null)
    {
        return $this->_cache_instance->set($key, $var, $flag, $expire);
    }
    
    protected function _get($key, &$flags = null)
    {
        return $this->_cache_instance->get($key, $flags);
    }
    
    public function make_cache_id($callback, $parameters)
    {   
        $cache_id_source = serialize($callback) . '_parameters_' . serialize($parameters) . '_unique_key_' . $this->_unique_key;
        $cache_id = md5($cache_id_source);
        
        return $cache_id;
    }
    
    public function call($callback, array $parameters = array(), $cache = true, $expire = null)
    {
        if (($this->_cache_instance === null) || ($this->_if_global_cache === false) || (!$cache)) {
            return call_user_func_array($callback, $parameters);
        }
    
        $cache_id = $this->make_cache_id($callback, $parameters);
    
        //获取缓存数据
        $data_serialize = $this->_get($cache_id);
        //var_dump($data_serialize); exit();
        if (($cache === false) || ($data_serialize === false)) {    //by gbfun 获取并存储、更新缓存数据
            ob_start();
            ob_implicit_flush(false);
            $return = call_user_func_array($callback, $parameters);
            $output = ob_get_clean();
            
            $data = array($output, $return);
            $data_serialize = serialize($data);
            $flag = null;    //by gbfun 用不到
            $save_result = $this->_set($cache_id, $data_serialize, $flag, $expire);
        } else {
            $data = unserialize($data_serialize);
            //var_dump($data); exit();
            $output = $data[0];
            $return = $data[1];
        }
    
        echo $output;  //by gbfun  !!  这里也有输出，如果调用下一层，有输出内容，则也会被输出
        return $return;
    }
    
    
    // 清除缓存
    public function flush()
    {
        if ($this->_cache_instance === null) {
            return false;
        }
        
        return $this->_cache_instance->flush();
    }
}
